const initialState = {
  commentList: [] as CommentType[],
  isLoading: false,

  originComment: {} as CommentType,
  replyComments: {
    end_id: '',
    last_id: '',
    results: [] as ReplyCommentType[],
    total_count: 0,
  },
};

type ActionType =
  | { type: 'comment/saveList'; payload: CommentType[] }
  | { type: 'comment/setLoading'; payload: boolean }
  | { type: 'comment/saveOrigiComment'; payload: CommentType }
  | { type: 'comment/clearOrigiComment' }
  | { type: 'comment/saveReplyList'; payload: typeof initialState.replyComments }
  | { type: 'comment/updateCommentById'; payload: string }
  | { type: 'comment/updateReplyCommentById'; payload: string }
  | { type: 'comment/updateOriginComment' };

export default function commentReducer(
  state = initialState,
  action: ActionType
): typeof initialState {
  switch (action.type) {
    case 'comment/saveList':
      return {
        ...state,
        commentList: [...action.payload],
      };
    case 'comment/setLoading':
      return {
        ...state,
        isLoading: action.payload,
      };

    case 'comment/saveOrigiComment':
      return {
        ...state,
        originComment: action.payload,
      };

    case 'comment/updateOriginComment':
      return {
        ...state,
        originComment: {
          ...state.originComment,
          is_liking: !state.originComment.is_liking,
          like_count: state.originComment.is_liking
            ? state.originComment.like_count - 1
            : state.originComment.like_count + 1,
        },
      };
    case 'comment/clearOrigiComment': {
      return {
        ...state,
        originComment: {} as CommentType,
      };
    }

    case 'comment/saveReplyList':
      return {
        ...state,
        replyComments: { ...action.payload },
      };

    case 'comment/updateCommentById': {
      return {
        ...state,
        commentList: updateListById(state.commentList, action.payload),
      };
    }

    case 'comment/updateReplyCommentById': {
      return {
        ...state,
        replyComments: {
          ...state.replyComments,
          results: updateListById(state.replyComments.results, action.payload),
        },
      };
    }

    default:
      return state;
  }
}

export type CommentType = {
  com_id: string;
  content: string;
  reply_count: number;
  pubdate: string;
  is_followed: boolean;
  is_liking: boolean;
  like_count: number;
  aut_id: string;
  aut_name: string;
  aut_photo: string;
};

export type ReplyCommentType = {
  com_id: string;
  content: string;
  reply_count: number;
  pubdate: string;
  is_followed: boolean;
  is_liking: boolean;
  like_count: number;
  aut_id: string;
  aut_name: string;
  aut_photo: string;
};

function updateListById(list: CommentType[], id: string): CommentType[] {
  const updateIndex = list.findIndex((item) => item.com_id === id);
  let updateItem = { ...list[updateIndex] };
  if (updateItem.is_liking) {
    updateItem.like_count--;
  } else {
    updateItem.like_count++;
  }
  updateItem.is_liking = !updateItem.is_liking;

  let newList = list.slice();
  newList[updateIndex] = updateItem;

  return newList;
}
